import express from 'express'
import path from 'path'
import fs from 'fs'
import { fileURLToPath } from 'url'

// 辅助方法
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
// 拿到当前文件的目录路径
const __dirname = path.dirname(fileURLToPath(import.meta.url))
// 定义 resolve 函数，用于拼接绝对路径
const resolve = (p) => path.resolve(__dirname, '..', p)

export async function createServer() {
  // 1. 创建 express 应用
  const app = express()

  // 2. 将 vite 创建的服务器以中间件的形式添加到 express 应用中，从而能够使用 vite 的热模块更新等特性
  const vite = await require('vite').createServer({
    server: {
      middlewareMode: true
    },
    appType: 'custom'
  })
  app.use(vite.middlewares)

  // 3. 处理请求
  app.use('*', async (req, res, next) => {
    // 拿到请求的 url
    const url = req.originalUrl
    // 读取出来的模板html文件的字符串
    let template = fs.readFileSync(resolve('index.html'), 'utf-8')
    // 调用 vite 的 transformIndexHtml 方法，注入一些必要的脚本和样式，为了使用 vite 的热更新等特性
    template = await vite.transformIndexHtml(url, template)
    // 读取服务端入口文件拿到 render 方法
    const render = (await vite.ssrLoadModule('/src/entry/server-entry.js')).render
    // 拿到的是Vue应用的html字符串，还可以拿到teleport的内容
    const [appHtml, teleportsStr] = await render(url)
    // 接下来做替换操作
    const html = template
      .replace(`<!--vue-ssr-outlet-->`, appHtml)
      .replace(/(\n|\r\n)\s*<!--app-teleports-->/, teleportsStr)
    // 返回给客户端
    res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
    try {
      // 读取html模板文件
    } catch (error) {
      vite.ssrFixStacktrace(error)
      console.error(error)
      res.status(500).send('Server Error')
      next()
    }
  })

  return app
}
